package com.ra.util;

import java.util.Map;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import javax.persistence.Transient;

import org.apache.commons.lang.StringEscapeUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang3.ObjectUtils;
import org.hibernate.annotations.LazyToOne;
import org.hibernate.annotations.LazyToOneOption;

import com.googlecode.cswish.annotation.QLFormula;
import com.ra.landlord.Zone;
import com.ra.system.Version;

/**
 * 地址信息
 * 
 * @author Jerry.Feng Date: 2014-07-30
 */
@Entity
@Table(name = "ra_area")
public class Address implements Version, AddressLocation {

	private Integer id;

	private AddressCode addressCode;
	
	private String name;
	
	// 冗余 addressCode.code (level = 1)
	private Integer province;
	
	// 冗余 addressCode.code (level = 2)
	private Integer city;
	
	// 冗余 addressCode.code (level = 3)
	private Integer district;
	
	// 经度
	private Double longitude;

	// 维度
	private Double latitude;
	
	private Integer version;
	
	private Integer status;
	
	private Zone zone1;
	
	private Zone zone2;
	
	private Zone zone3;
	
	// 地址来源: ip
	private Boolean fromIp;
	
	// transient, 距离
	private Double distance;
	
	@Id
	@GeneratedValue
	@Column(name = "area_id")
	public Integer getId() {
		return id;
	}

	public void setId(Integer id) {
		this.id = id;
	}

	@Column(name = "area_Name")
	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}
	
	@Column(name = "province_id")
	public Integer getProvince() {
		return province;
	}

	public void setProvince(Integer province) {
		this.province = province;
	}

	@Column(name = "city_id")
	public Integer getCity() {
		return city;
	}

	public void setCity(Integer city) {
		this.city = city;
	}

	@Column(name = "district_id")
	public Integer getDistrict() {
		return district;
	}

	public void setDistrict(Integer district) {
		this.district = district;
	}

	@ManyToOne(fetch=FetchType.LAZY)
	@LazyToOne(LazyToOneOption.PROXY)
	public AddressCode getAddressCode() {
		return addressCode;
	}

	public void setAddressCode(AddressCode addressCode) {
		this.addressCode = addressCode;
	}

	@Column(name = "version_id")
	public Integer getVersion() {
		return version;
	}

	public void setVersion(Integer version) {
		this.version = version;
	}

	@Column(name = "data_status")
	public Integer getStatus() {
		return status;
	}

	public void setStatus(Integer status) {
		this.status = status;
	}
	
	public Double getLongitude() {
		return longitude;
	}

	public void setLongitude(Double longitude) {
		this.longitude = longitude;
	}

	public Double getLatitude() {
		return latitude;
	}

	public void setLatitude(Double latitude) {
		this.latitude = latitude;
	}

	@ManyToOne(cascade={CascadeType.MERGE, CascadeType.PERSIST}, fetch=FetchType.LAZY)
	@JoinColumn(name = "zone1_id")
	public Zone getZone1() {
		return zone1;
	}

	public void setZone1(Zone zone1) {
		this.zone1 = zone1;
	}

	@ManyToOne(cascade={CascadeType.MERGE, CascadeType.PERSIST}, fetch=FetchType.LAZY)
	@JoinColumn(name = "zone2_id")
	public Zone getZone2() {
		return zone2;
	}

	public void setZone2(Zone zone2) {
		this.zone2 = zone2;
	}

	@ManyToOne(cascade={CascadeType.MERGE, CascadeType.PERSIST}, fetch=FetchType.LAZY)
	@JoinColumn(name = "zone3_id")
	public Zone getZone3() {
		return zone3;
	}

	public void setZone3(Zone zone3) {
		this.zone3 = zone3;
	}

	/**
	 * 由province, city, district + name组合而成
	 * 
	 * @return
	 */
	@Transient
	@QLFormula(value = ":qlFormulaForGetFullName", isColumn = false)
	public String getFullName() {
		
		String areaCode = AreaParser.CHINA_ID ;
		if (getProvince() != null) {
			areaCode += "_" + getProvince();
		}
		if (getCity() != null) {
			areaCode += "_" + getCity();
		}
		if (getDistrict() != null) {
			areaCode += "_" + getDistrict();
		}
		String areaPreName = AreaParser.getAreaName(areaCode);
		
		if (getName() == null) {
			return areaPreName;
		} else {
			return areaPreName + getName();
		}
	}
	
	public static String qlFormulaForGetFullName(Map<String, Object> model) {
		String fullName = (String) model.get("fullName");
		if (StringUtils.isEmpty(fullName)) {
			return "";
		} else {
			String where;
			String[] codes = AreaParser.findAreaCode(fullName);
			if (codes == null) {
				where = "a.name like '%" + StringEscapeUtils.escapeSql(fullName) + "%'";
			} else {
				if (codes[2] != null) {
					where = "a.province=" + codes[0] + " and a.city=" + codes[1] + " and a.district=" + codes[2];
				} else if (codes[1] != null) {
					where = "a.province=" + codes[0] + " and a.city=" + codes[1];
				} else {
					where = "a.province=" + codes[0];
				}
			}
			return where;
		}
	}

	public Boolean getFromIp() {
		return fromIp;
	}

	public void setFromIp(Boolean fromIp) {
		this.fromIp = fromIp;
	}

	@Transient
	public Double getDistance() {
		return distance;
	}

	public void setDistance(Double distance) {
		this.distance = distance;
	}
}
